#include <unistd.h>

.globl __clone
__clone:						# __clone(clone_flags, stack, fn, arg)
	pushl %ebp					# maintain ebp chain
	movl %esp, %ebp

	pushl %edx					# save old registers
	pushl %ecx
	pushl %ebx
	pushl %edi

	movl 0x8(%ebp), %edx		# load clone_flags
	movl 0xc(%ebp), %ecx		# load stack
	movl 0x10(%ebp), %ebx		# load fn
	movl 0x14(%ebp), %edi		# load arg

	movl $SYS_clone, %eax		# load SYS_clone
	int $T_SYSCALL				# syscall

	cmpl $0x0, %eax				# pid ? child or parent ?
	je 1f						# eax == 0, goto 1;

	# parent
	popl %edi					# restore registers
	popl %ebx
	popl %ecx
	popl %edx

	leave						# restore ebp
	ret

	# child
1:
	pushl %edi
	call *%ebx					# call fn(arg)

	movl %eax, %edx				# save exit_code
	movl $SYS_exit, %eax		# load SYS_exit
	int $T_SYSCALL				# int SYS_exit

spin:							# error ?
	jmp spin

